// -----------------------------
// Author: 		Dhaenens Gert	
// Creation: 	12/4/2014 6:14:08 PM				
// -----------------------------

#include "GUIPass.h"

#include "Application.h"
#include "RenderManager.h"
#include "FileManager.h"
#include "Window.h"

#include "Scene.h"

#define DISPATCH_NUM_THREADS_X	16
#define DISPATCH_NUM_THREADS_Y	16
#define DISPATCH_NUM_THREADS_Z	1

GUIPass::GUIPass(RenderManager* lpRenderManager, const RenderTargets& targets)
	: RenderPass(lpRenderManager, "GUI", targets)
	, m_lpGUICopyShader(nullptr)
	, m_ThreadCountX(0)
	, m_ThreadCountY(0)
	, m_ThreadCountZ(0)
{
}

GUIPass::~GUIPass()
{
	NullRelease(&m_lpGUICopyShader);
}

void GUIPass::Init(Application* lpApp)
{
	TString shaderName = lpApp->GetFiles()->GetFileName(_T("Shader_GUICopy"));
	m_lpGUICopyShader = ShaderCompiler::LoadComputeFromFile(m_lpRenderManager->GetDevice(), shaderName.c_str());

	m_ThreadCountX = (lpApp->GetWindow()->GetWidth() + DISPATCH_NUM_THREADS_X) / DISPATCH_NUM_THREADS_X;
	m_ThreadCountY = (lpApp->GetWindow()->GetHeight() + DISPATCH_NUM_THREADS_Y) / DISPATCH_NUM_THREADS_Y;
	m_ThreadCountZ = 1;
}
void GUIPass::Apply(Application* lpApp, Scene* lpScene)
{
	IRenderDevice* lpDevice = m_lpRenderManager->GetDevice();

	// Begin the 2D Drawing
	m_Targets.RenderTarget2D->BeginDraw();
	m_Targets.RenderTarget2D->Clear(0.0f, 0.0f, 0.0f, 0.0f);

	// Call the Scene OnGUI Pass
	lpScene->OnGUI(lpApp, m_Targets.RenderTarget2D);

	// End the 2D Drawing
	m_Targets.RenderTarget2D->EndDraw();

	// Set the Render Targets to Null
	lpDevice->SetRenderTarget(nullptr, nullptr);

	// Set the Compute Shader
	lpDevice->SetComputeShader(m_lpGUICopyShader);
	 
	// Bind the Targets
	m_lpGUICopyShader->SetTargetAsResource(0, m_Targets.PostRenderTarget3D);
	m_lpGUICopyShader->SetTarget2DAsResource(1, m_Targets.RenderTarget2D);
	m_lpGUICopyShader->SetTargetAsUav(0, m_Targets.OutputTarget);  

	// Dispatch
	lpDevice->Dispatch(m_ThreadCountX, m_ThreadCountY, m_ThreadCountZ);

	// Unbind the Targets
	m_lpGUICopyShader->ClearResource(0);
	m_lpGUICopyShader->ClearResource(1);
	m_lpGUICopyShader->ClearUav(0);
}
void GUIPass::UpdateTargets(Application* lpApp, const RenderTargets& targets)
{
	RenderPass::UpdateTargets(lpApp, targets);
	
	// Update Thread Counts
	m_ThreadCountX = (lpApp->GetWindow()->GetWidth() + DISPATCH_NUM_THREADS_X) / DISPATCH_NUM_THREADS_X;
	m_ThreadCountY = (lpApp->GetWindow()->GetHeight() + DISPATCH_NUM_THREADS_Y) / DISPATCH_NUM_THREADS_Y;
	m_ThreadCountZ = 1;
}